from logging import Logger
from typing import Any

from ducktape.cluster.cluster import ClusterNode
from ducktape.cluster.cluster_spec import ClusterSpec as ClusterSpec
from ducktape.command_line.defaults import ConsoleDefaults as ConsoleDefaults
from ducktape.errors import TimeoutError as TimeoutError
from ducktape.template import TemplateRenderer as TemplateRenderer
from ducktape.tests.test import TestContext

class ServiceIdFactory:
    def generate_service_id(self, service: Any) -> str: ...

class MultiRunServiceIdFactory:
    run_number: int

    def __init__(self, run_number: int = 1) -> None: ...
    def generate_service_id(self, service: Any) -> str: ...

service_id_factory: ServiceIdFactory

class Service(TemplateRenderer):
    logs: dict[str, dict[str, Any]]
    service_id_factory: ServiceIdFactory
    cluster_spec: ClusterSpec
    context: TestContext
    nodes: list[ClusterNode]
    skip_nodes_allocation: bool

    def __init__(
        self,
        context: Any,
        num_nodes: int | None = ...,
        cluster_spec: ClusterSpec | None = ...,
        *args: Any,
        **kwargs: Any,
    ) -> None: ...
    @staticmethod
    def setup_cluster_spec(
        num_nodes: int | None = ..., cluster_spec: ClusterSpec | None = ...
    ) -> ClusterSpec: ...
    @property
    def num_nodes(self) -> int: ...
    @property
    def local_scratch_dir(self) -> str: ...
    @property
    def service_id(self) -> str: ...
    @property
    def logger(self) -> Logger: ...
    @property
    def cluster(self) -> Any: ...
    @property
    def allocated(self) -> bool: ...
    def who_am_i(self, node: ClusterNode | None = ...) -> str: ...
    def allocate_nodes(self) -> None: ...
    def start(self, **kwargs: Any) -> None: ...
    def start_node(self, node: ClusterNode, **kwargs: Any) -> None: ...
    def wait(self, timeout_sec: int = 600) -> None: ...
    def wait_node(self, node: ClusterNode, timeout_sec: float | None = ...) -> bool: ...
    def stop(self, **kwargs: Any) -> None: ...
    def stop_node(self, node: ClusterNode, **kwargs: Any) -> None: ...
    def clean(self, **kwargs: Any) -> None: ...
    def clean_node(self, node: ClusterNode, **kwargs: Any) -> None: ...
    def free(self) -> None: ...
    def run(self) -> None: ...
    def get_node(self, idx: int) -> ClusterNode: ...
    def idx(self, node: ClusterNode) -> int: ...
    def close(self) -> None: ...
    @staticmethod
    def run_parallel(*args: Service) -> None: ...
    def to_json(self) -> dict[str, Any]: ...
